// *************************************************************************************************
//
// MK3D Engine
// --------------------------------------
// Copyright (C) 2007-2011 Zeb (mailto: zebbey@gmail.com)
//
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//
// *************************************************************************************************

#ifndef __H_MK_FT_FONT__
#define __H_MK_FT_FONT__

#include "mk_resource.h"
#include "mk_texture.h"
#include "mk_memory_block.h"

// FreeType2
#include "ft2build.h"
#include FT_FREETYPE_H

namespace MK3DE
{
	enum FONT_BORDER_TYPE
	{
		FBT_NONE,
		FBT_BORDER,
		FBT_PROJECTION,
	};

	class MK3DE_API CFTFont : public CResource
	{
	private:
		static FT_Library       _library;
		static wchar_t          _errorChar;

	public:
		static BOOL Create();
		static void Destroy();

	private:
		struct _WordLocate
		{
			unsigned short uX;
			unsigned short uY;
			unsigned short uTextureIdx;
			unsigned short uReserved;
		};

		struct _WordDimension
		{
			unsigned short uWidth;
			unsigned short uHeight;
			short OffsetX;
			short OffsetY;
			unsigned short uAdvanceX;
			unsigned short uReserved;
		};

		struct _TextureUsedDesc
		{
			unsigned long uUsedWidth;
			unsigned long uUsedHeightMin;
			unsigned long uUsedHeightMax;
		};

	public:
		CFTFont(const char* fileName, BOOL bAntialiased, DWORD points);
		~CFTFont();

		RESOURCE_TYPE GetType() { return RES_T_FTFONT; }
		std::string GetResourceName();

		BOOL Load();

		//! Draw text.
		/**
		\param x : x of position.
		\param y : y of position.
		\param dwColor : text's color.
		\param txt : text string.
		\param num : how many chars will be rendered. Pass 0 will render all c-style string.
		\return : If the method succeeds, return TRUE or return FALSE. 
		*/
		BOOL DrawText(int x, int y, DWORD dwColor, const wchar_t* txt, DWORD num);

		//! Calculate text's dimension.
		/**
		\param txt : text string.
		\param count : how many chars will be calculated. Pass 0 will calculate all c-style string.
		\param width[out] : string's width.
		\param height[out] : string's height.
		\return : If the method succeeds, return TRUE or return FALSE. 
		*/
		BOOL GetTextDimension(const wchar_t* txt, DWORD count, float* width, float* height);

		//! Set border parameters.
		void SetBorderParam(FONT_BORDER_TYPE type, DWORD color, DWORD weight);

		// !Set clip rect.
		void SetClipRect(BOOL bEnable, float left, float top, float right, float bottom);

	private:
		FT_Face _ftFace;

		CMemoryBlock _block;

		_WordLocate _wordLocate[0xFFFF];
		_WordDimension _wordDimension[0xFFFF];
		std::vector<CTexture2D*> _vecFontTexture;
		std::vector<_TextureUsedDesc> _vecTextureUsedDesc;

		BOOL _bAntialiased;
		DWORD _points;
		FONT_BORDER_TYPE _borderType;
		DWORD _borderWeight;
		DWORD _borderColor;

		BOOL _enableClip;
		float _clipLeft;
		float _clipTop;
		float _clipRight;
		float _clipBottom;

	private:
		HRESULT PaintTexture(wchar_t c);
		HRESULT LoadGlyph(wchar_t c);
		int CheckFontTexture(unsigned long uWidth, unsigned long uHeight, _TextureUsedDesc& usedDesc);
		DWORD SelectTextureSize();
		void WriteTextureA8R8G8B8Mono(unsigned short uWidth, unsigned short uHeight, void* pData, DWORD pitch);
		void WriteTextureA8R8G8B8Gray8Bit(unsigned short uWidth, unsigned short uHeight, void* pData, DWORD pitch );
		void DrawChar(wchar_t c, int x, int y, DWORD dwColor, int& advanceX);
	};
};

#endif // __H_MK_FT_FONT__